package com.wingice.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.wingice.exception.BusinessException;
import com.wingice.system.entity.SysAttachment;
import com.wingice.system.service.FileUploadService;
import com.wingice.system.service.SysAttachmentService;
import com.wingice.utils.file.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传相关接口实现类
 */
@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {

    @Value("${web.upload}")
    public String upload;

    @Resource
    private SysAttachmentService attachmentService;

    @Override
    public SysAttachment uploadSingleFile(String fileUrl, String fileName, MultipartFile file) {
        SysAttachment erpAttachment = commonFileUpload(fileUrl, fileName, file);
        attachmentService.save(erpAttachment);
        return erpAttachment;
    }

    @Override
    public SysAttachment uploadSingleFile(String fileUrl, String fileName, MultipartFile file, List<Integer> validateFileTypeList) {
        SysAttachment erpAttachment = commonFileUpload(fileUrl, fileName, file, validateFileTypeList);
        attachmentService.save(erpAttachment);
        return erpAttachment;
    }

    @Override
    public SysAttachment uploadSingleFile(String fileUrl, String fileName, MultipartFile file, Map<Integer, Long> fileTypeSizeMap) {
        SysAttachment erpAttachment = commonFileUpload(fileUrl, fileName, file, fileTypeSizeMap);
        attachmentService.save(erpAttachment);
        return erpAttachment;
    }

    @Override
    public List<SysAttachment> uploadBatchFile(String fileUrl, List<MultipartFile> files) {
        List<SysAttachment> attachments = new ArrayList<>();
        for (MultipartFile file : files) {
            SysAttachment erpAttachment = commonFileUpload(fileUrl, null, file);
            attachments.add(erpAttachment);
        }
        attachmentService.saveBatch(attachments);
        return attachments;
    }

    @Override
    public List<SysAttachment> uploadBatchFile(String fileUrl, List<MultipartFile> files, List<Integer> validateFileTypeList) {
        List<SysAttachment> attachments = new ArrayList<>();
        for (MultipartFile file : files) {
            SysAttachment erpAttachment = commonFileUpload(fileUrl, null, file, validateFileTypeList);
            attachments.add(erpAttachment);
        }
        attachmentService.saveBatch(attachments);
        return attachments;
    }

    @Override
    public List<SysAttachment> uploadBatchFile(String fileUrl, List<MultipartFile> files, Map<Integer, Long> fileTypeSizeMap) {
        List<SysAttachment> attachments = new ArrayList<>();
        for (MultipartFile file : files) {
            SysAttachment erpAttachment = commonFileUpload(fileUrl, null, file, fileTypeSizeMap);
            attachments.add(erpAttachment);
        }
        attachmentService.saveBatch(attachments);
        return attachments;
    }


    private SysAttachment commonFileUpload(String fileUrl, String fileName, MultipartFile file, List<Integer> validateFileTypeList) {
        // 参数校验
        FileUtil.validateFile(file, validateFileTypeList);
        return fileUpload(fileUrl, fileName, file);
    }

    private SysAttachment commonFileUpload(String fileUrl, String fileName, MultipartFile file, Map<Integer, Long> fileTypeSizeMap) {
        // 参数校验
        FileUtil.validateFile(file, fileTypeSizeMap);
        return fileUpload(fileUrl, fileName, file);
    }

    private SysAttachment commonFileUpload(String fileUrl, String fileName, MultipartFile file) {
        return fileUpload(fileUrl, fileName, file);
    }

    private SysAttachment fileUpload(String fileUrl, String fileName, MultipartFile file) {
        SysAttachment erpAttachment;
        try {
            String originFileName = file.getOriginalFilename();
            assert originFileName != null;
            String newFileName = UUID.randomUUID() + originFileName.substring(originFileName.lastIndexOf("."));
            if (StringUtils.isNotBlank(fileName)) {
                originFileName = fileName + originFileName.substring(originFileName.lastIndexOf("."));
            }
            String relDirectory = upload.replaceAll("file:", "") + fileUrl;

            File fi = new File(relDirectory);
            if (!fi.isDirectory()) {
                //先得到文件的上级目录，并创建上级目录，在创建文件
                fi.mkdirs();
            }
            File uploadFile = new File(relDirectory, newFileName);
            file.transferTo(uploadFile);
            erpAttachment = new SysAttachment();
            erpAttachment.setFileName(newFileName);
            erpAttachment.setFileOriginName(originFileName);
            erpAttachment.setFilePath(fileUrl.startsWith("/") ? fileUrl + newFileName : "/" + fileUrl + newFileName);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new BusinessException(e.getMessage());
        }
        return erpAttachment;
    }


    @Override
    public Boolean deleteSingleFile(String fileId) {
        SysAttachment erpAttachment = attachmentService.getById(fileId);
        if (ObjectUtil.isNotNull(erpAttachment)) {
            // 删除文件
            FileUtil.deleteFile(upload.replaceAll("file:", "") + erpAttachment.getFilePath());
        }
        return attachmentService.removeById(fileId);
    }

    @Override
    public Boolean deleteBatchFile(List<String> fileIds) {
        List<SysAttachment> erpAttachmentList = attachmentService.listByIds(fileIds);
        for (SysAttachment erpAttachment : erpAttachmentList) {
            // 删除文件
            FileUtil.deleteFile(upload.replaceAll("file:", "") + erpAttachment.getFilePath());
        }
        return attachmentService.removeByIds(fileIds);
    }
}
